#include "stdafx.h"

namespace classifier_test
{

hyperplane_generator::hyperplane_generator()
{
}

hyperplane_generator::hyperplane_generator(const hyperplane_generator& Val)
	: conceptual_data_generator(Val)
{
	ConceptCount = Val.ConceptCount;
	Dim = Val.Dim;
	Scheme = Val.Scheme;
	Planes = Val.Planes;
}

smart_ptr<conceptual_data_generator> hyperplane_generator::clone() const
{
	return make_smart_ptr(new hyperplane_generator(*this));
}

const record_scheme& hyperplane_generator::get_scheme() const
{
	return Scheme;
}

int hyperplane_generator::get_concept_count() const
{
	return ConceptCount;
}

void hyperplane_generator::set_concept_count(int Val)
{
	ConceptCount = Val;
}

int hyperplane_generator::get_dimensionality() const
{
	return Dim;
}

void hyperplane_generator::set_dimensionality(int Val)
{
	Dim = Val;
}

void hyperplane_generator::open()
{
	Scheme.resize(Dim + 1);
	for (int I = 0; I < Dim; I++)
	{
		Scheme[I].name = "Att" + to_string(I);
		Scheme[I].type = cont_attr;
		Scheme[I].cont.lower_bound = 0;
		Scheme[I].cont.upper_bound = 1;
	}
	Scheme[Dim].name = "class";
	Scheme[Dim].type = discr_attr;
	Scheme[Dim].discr.add("+");
	Scheme[Dim].discr.add("-");
	Planes.assign(ConceptCount, vector<double>(Dim));
	for (int I = 0; I < ConceptCount; I++) for (int J = 0; J < Dim; J++)
		Planes[I][J] = uniform() * 2 - 1;
}

void hyperplane_generator::close()
{
	Scheme.clear();
	reset_vector(Planes);
}

void hyperplane_generator::generate(int Con, record& Rec) const
{
	Rec.resize(Dim + 1);
	for (int I = 0; I < Dim; I++) Rec[I].cont = cont_value(uniform());
	double InnerProd = 0;
	for (int I = 0; I < Dim; I++) InnerProd += (Rec[I].cont - 0.5) * Planes[Con][I];
	if (InnerProd >= 0) Rec[Dim].discr = 0;
	else Rec[Dim].discr = 1;
}

}
